home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 176-200 / 190 / nethack / twee.zoo / mklev.c < prev    next >
C/C++ Source or Header  |  1988-07-25  |  22KB  |  987 lines

  1. /*    SCCS Id: @(#)mklev.c    2.3     87/12/12
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include "hack.h"
  5.  
  6. extern char *getlogin(), *getenv();
  7. extern struct monst *makemon(), *mkmon_at();
  8. extern struct obj *mkobj_at(), *mksobj_at();
  9. extern struct trap *maketrap();
  10.  
  11. #ifdef RPH
  12. extern struct permonst pm_medusa;
  13. #endif
  14.  
  15. #ifdef STOOGES
  16. extern struct permonst pm_larry, pm_curly, pm_moe;
  17. #endif
  18.  
  19. #define somex() ((int)(rand()%(croom->hx-croom->lx+1))+croom->lx)
  20. #define somey() ((int)(rand()%(croom->hy-croom->ly+1))+croom->ly)
  21.  
  22. #include "mkroom.h"
  23. #define XLIM    4    /* define minimum required space around a room */
  24. #define YLIM    3
  25. boolean secret;     /* TRUE while making a vault: increase [XY]LIM */
  26. extern struct mkroom rooms[MAXNROFROOMS+1];
  27. int smeq[MAXNROFROOMS+1];
  28. extern coord doors[DOORMAX];
  29. int doorindex;
  30. struct rm zerorm;
  31. int comp();
  32. schar nxcor;
  33. boolean goldseen;
  34. int nroom;
  35. extern xchar xdnstair,xupstair,ydnstair,yupstair;
  36.  
  37. /* Definitions used by makerooms() and addrs() */
  38. #define MAXRS    50    /* max lth of temp rectangle table - arbitrary */
  39. struct rectangle {
  40.     xchar rlx,rly,rhx,rhy;
  41. } rs[MAXRS+1];
  42. int rscnt,rsmax;    /* 0..rscnt-1: currently under consideration */
  43.             /* rscnt..rsmax: discarded */
  44.  
  45. makelevel()
  46. {
  47.     register struct mkroom *croom, *troom;
  48.     register unsigned tryct;
  49. #ifndef REGBUG
  50.     register
  51. #endif
  52.          int x,y;
  53. #ifdef SPIDERS            /* always put a web with a spider */
  54.     struct monst *tmonst;
  55. #endif
  56.  
  57.     nroom = 0;
  58.     doorindex = 0;
  59.     rooms[0].hx = -1;    /* in case we are in a maze */
  60.  
  61.     for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
  62.         levl[x][y] = zerorm;
  63.  
  64.     oinit();        /* assign level dependent obj probabilities */
  65. #ifdef RPH
  66.     if (u.wiz_level == 0) {
  67.         u.medusa_level = rn1(3, (MAXLEVEL > 30) ? 25 : (MAXLEVEL - 4) );
  68.         u.wiz_level    = rn1(MAXLEVEL-u.medusa_level, u.medusa_level)+1;
  69. #ifdef STOOGES
  70.         u.stooge_level = rn1(6,4);
  71. #endif
  72.     }
  73.     if (dlevel > u.medusa_level) {
  74.         makemaz();
  75.         return;
  76.     }
  77. #else
  78.     if(dlevel >= rn1(3, 26)) {      /* there might be several mazes */
  79.         makemaz();
  80.         return;
  81.     }
  82. #endif
  83.     /* construct the rooms */
  84.     nroom = 0;
  85.     secret = FALSE;
  86.     (void) makerooms();
  87.  
  88.     /* construct stairs (up and down in different rooms if possible) */
  89.     croom = &rooms[rn2(nroom)];
  90.     xdnstair = somex();
  91.     ydnstair = somey();
  92.     levl[xdnstair][ydnstair].scrsym = DN_SYM;
  93.     RM_SET_TYP(levl[xdnstair][ydnstair], STAIRS);
  94. #ifdef RPH
  95.     { struct monst *mtmp;
  96.     if (dlevel == u.medusa_level)
  97.         if (mtmp = makemon(PM_MEDUSA, xdnstair, ydnstair))
  98.         mtmp->msleep = 1;
  99.     }
  100. #endif
  101. #ifdef STOOGES
  102.     { struct monst *mtmp;
  103.     if (dlevel == u.stooge_level) {    /* probably should use enexto */
  104.         mtmp = makemon(PM_MOE, xdnstair, ydnstair);
  105.         if (mtmp) mtmp->isstooge = 1;
  106.         if (mtmp) mtmp->mpeaceful = 1;
  107.         if (goodpos(xdnstair+1, ydnstair))
  108.             mtmp = makemon(PM_LARRY, xdnstair+1, ydnstair);
  109.         else if (goodpos(xdnstair-1, ydnstair))
  110.             mtmp = makemon(PM_LARRY, xdnstair-1, ydnstair);
  111.         if (mtmp) mtmp->isstooge = 1;
  112.         if (mtmp) mtmp->mpeaceful = 1;
  113.         if (goodpos(xdnstair, ydnstair+1))
  114.             mtmp = makemon(PM_CURLY, xdnstair, ydnstair+1);
  115.         else if (goodpos(xdnstair, ydnstair-1))
  116.             mtmp = makemon(PM_CURLY, xdnstair, ydnstair-1);
  117.         if (mtmp) mtmp->isstooge = 1;
  118.         if (mtmp) mtmp->mpeaceful = 1;
  119.         }
  120.     }
  121. #endif
  122.     if(nroom > 1) {
  123.         troom = croom;
  124.         croom = &rooms[rn2(nroom-1)];
  125.         if(croom >= troom) croom++;
  126.     }
  127.     xupstair = somex();     /* %% < and > might be in the same place */
  128.     yupstair = somey();
  129.     levl[xupstair][yupstair].scrsym = UP_SYM;
  130.     RM_SET_TYP(levl[xupstair][yupstair], STAIRS);
  131.  
  132.     /* for each room: put things inside */
  133.     for(croom = rooms; croom->hx > 0; croom++) {
  134.  
  135.         /* put a sleeping monster inside */
  136.         /* Note: monster may be on the stairs. This cannot be
  137.            avoided: maybe the player fell through a trapdoor
  138.            while a monster was on the stairs. Conclusion:
  139.            we have to check for monsters on the stairs anyway. */
  140. #ifdef BVH
  141.         if(has_amulet() || !rn2(3))
  142. #else
  143.         if (!rn2(3))
  144. #endif
  145. #ifndef SPIDERS
  146.             (void)makemon((struct permonst *) 0, somex(), somey());
  147. #else
  148.         {
  149.             x = somex(); y = somey();
  150.             tmonst=makemon((struct permonst *) 0, x,y);
  151.             if (tmonst && tmonst->data->mlet == 's')
  152.             (void) maketrap (x,y,WEB);
  153.         }
  154. #endif
  155.         /* put traps and mimics inside */
  156.         goldseen = FALSE;
  157.         while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
  158.         if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey());
  159. #ifdef FOUNTAINS
  160.         if(!rn2(10)) mkfount(0,croom);
  161. #endif
  162. #ifdef SINKS
  163.         if(!rn2(80)) mksink(croom);
  164. #endif
  165.         if(!rn2(3)) {
  166.             (void) mkobj_at(0, somex(), somey());
  167.             tryct = 0;
  168.             while(!rn2(5)) {
  169.                 if(++tryct > 100){
  170.                     printf("tryct overflow4\n");
  171.                     break;
  172.                 }
  173.                 (void) mkobj_at(0, somex(), somey());
  174.             }
  175.         }
  176.     }
  177.  
  178.     qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
  179.     makecorridors();
  180.     make_niches();
  181.  
  182.     /* make a secret treasure vault, not connected to the rest */
  183.     if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) {
  184.         troom = &rooms[nroom];
  185.         secret = TRUE;
  186.         if(makerooms()) {
  187.             troom->rtype = VAULT;        /* treasure vault */
  188.             for(x = troom->lx; x <= troom->hx; x++)
  189.             for(y = troom->ly; y <= troom->hy; y++)
  190.                 mkgold((long)(rnd(dlevel*100) + 50), x, y);
  191.             if(!rn2(3))
  192.                 makevtele();
  193.         }
  194.     }
  195.  
  196. #ifdef WIZARD
  197.     if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else
  198. #endif
  199.     if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkroom(SHOPBASE);
  200.     else
  201. #ifdef NEWCLASS
  202.     if(dlevel > 4 && !rn2(6)) mkroom(COURT);
  203.     else
  204. #endif
  205.     if(dlevel > 6 && !rn2(7)) mkroom(ZOO);
  206.     else
  207.     if(dlevel > 9 && !rn2(5)) mkroom(BEEHIVE);
  208.     else
  209.     if(dlevel > 11 && !rn2(6)) mkroom(MORGUE);
  210.     else
  211. #ifdef SAC
  212.     if(dlevel > 14 && !rn2(4)) mkroom(BARRACKS);
  213.     else
  214. #endif
  215.     if(dlevel > 18 && !rn2(6)) mkroom(SWAMP);
  216. }
  217.  
  218. makerooms() {
  219. register struct rectangle *rsp;
  220. register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
  221. int tryct = 0, xlim, ylim;
  222.  
  223.     /* init */
  224.     xlim = XLIM + secret;
  225.     ylim = YLIM + secret;
  226.     if(nroom == 0) {
  227.         rsp = rs;
  228.         rsp->rlx = rsp->rly = 0;
  229.         rsp->rhx = COLNO-1;
  230.         rsp->rhy = ROWNO-1;
  231.         rsmax = 1;
  232.     }
  233.     rscnt = rsmax;
  234.  
  235.     /* make rooms until satisfied */
  236.     while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
  237.         if(!secret && nroom > (MAXNROFROOMS/3) &&
  238.            !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
  239.             return(0);
  240.  
  241.         /* pick a rectangle */
  242.         rsp = &rs[rn2(rscnt)];
  243.         hx = rsp->rhx;
  244.         hy = rsp->rhy;
  245.         lx = rsp->rlx;
  246.         ly = rsp->rly;
  247.  
  248.         /* find size of room */
  249.         if(secret)
  250.             dx = dy = 1;
  251.         else {
  252.             dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
  253.             dy = 2 + rn2(4);
  254.             if(dx*dy > 50)
  255.                 dy = 50/dx;
  256.         }
  257.  
  258.         /* look whether our room will fit */
  259.         if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) {
  260.                     /* no, too small */
  261.                     /* maybe we throw this area out */
  262.             if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
  263.                 rscnt--;
  264.                 rs[rsmax] = *rsp;
  265.                 *rsp = rs[rscnt];
  266.                 rs[rscnt] = rs[rsmax];
  267.                 tryct = 0;
  268.             } else
  269.                 tryct++;
  270.             continue;
  271.         }
  272.  
  273.         lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
  274.         lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
  275.         hix = lowx + dx;
  276.         hiy = lowy + dy;
  277.  
  278.         if(maker(lowx, dx, lowy, dy)) {
  279.             if(secret) return(1);
  280.             addrs(lowx-1, lowy-1, hix+1, hiy+1);
  281.             tryct = 0;
  282.         } else
  283.             if(tryct++ > 100)
  284.                 break;
  285.     }
  286.     return(0);      /* failed to make vault - very strange */
  287. }
  288.  
  289. addrs(lowx,lowy,hix,hiy)
  290. register int lowx,lowy,hix,hiy;
  291. {
  292.     register struct rectangle *rsp;
  293.     register int lx,ly,hx,hy,xlim,ylim;
  294.     boolean discarded;
  295.  
  296.     xlim = XLIM + secret;
  297.     ylim = YLIM + secret;
  298.  
  299.     /* walk down since rscnt and rsmax change */
  300.     for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
  301.  
  302.         if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
  303.            (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
  304.             continue;
  305.         if((discarded = (rsp >= &rs[rscnt]))) {
  306.             *rsp = rs[--rsmax];
  307.         } else {
  308.             rsmax--;
  309.             rscnt--;
  310.             *rsp = rs[rscnt];
  311.             if(rscnt != rsmax)
  312.                 rs[rscnt] = rs[rsmax];
  313.         }
  314.         if(lowy - ly > 2*ylim + 4)
  315.             addrsx(lx,ly,hx,lowy-2,discarded);
  316.         if(lowx - lx > 2*xlim + 4)
  317.             addrsx(lx,ly,lowx-2,hy,discarded);
  318.         if(hy - hiy > 2*ylim + 4)
  319.             addrsx(lx,hiy+2,hx,hy,discarded);
  320.         if(hx - hix > 2*xlim + 4)
  321.             addrsx(hix+2,ly,hx,hy,discarded);
  322.     }
  323. }
  324.  
  325. addrsx(lx,ly,hx,hy,discarded)
  326. register int lx,ly,hx,hy;
  327. boolean discarded;        /* piece of a discarded area */
  328. {
  329.     register struct rectangle *rsp;
  330.  
  331.     /* check inclusions */
  332.     for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
  333.         if(lx >= rsp->rlx && hx <= rsp->rhx &&
  334.            ly >= rsp->rly && hy <= rsp->rhy)
  335.             return;
  336.     }
  337.  
  338.     /* make a new entry */
  339.     if(rsmax >= MAXRS) {
  340. #ifdef WIZARD
  341.         if(wizard) pline("MAXRS may be too small.");
  342. #endif
  343.         return;
  344.     }
  345.     rsmax++;
  346.     if(!discarded) {
  347.         *rsp = rs[rscnt];
  348.         rsp = &rs[rscnt];
  349.         rscnt++;
  350.     }
  351.     rsp->rlx = lx;
  352.     rsp->rly = ly;
  353.     rsp->rhx = hx;
  354.     rsp->rhy = hy;
  355. }
  356.  
  357. comp(x,y)
  358. register struct mkroom *x,*y;
  359. {
  360.     if(x->lx < y->lx) return(-1);
  361.     return(x->lx > y->lx);
  362. }
  363.  
  364. finddpos(cc, xl,yl,xh,yh)
  365. coord    *cc;
  366. int    xl,yl,xh,yh;
  367. {
  368.     register x,y;
  369.  
  370.     x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
  371.     y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
  372.     if(okdoor(x, y))
  373.         goto gotit;
  374.  
  375.     for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  376.         if(okdoor(x, y))
  377.             goto gotit;
  378.  
  379.     for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  380.         if(RM_TYP(levl[x][y]) == DOOR || RM_TYP(levl[x][y]) == SDOOR)
  381.             goto gotit;
  382.     /* cannot find something reasonable -- strange */
  383.     x = xl;
  384.     y = yh;
  385. gotit:
  386.     cc->x = x;
  387.     cc->y = y;
  388.     return(0);
  389. }
  390.  
  391. /* see whether it is allowable to create a door at [x,y] */
  392. okdoor(x,y)
  393. register x,y;
  394. {
  395.     if(RM_TYP(levl[x-1][y]) == DOOR || RM_TYP(levl[x+1][y]) == DOOR ||
  396.        RM_TYP(levl[x][y+1]) == DOOR || RM_TYP(levl[x][y-1]) == DOOR ||
  397.        RM_TYP(levl[x-1][y]) == SDOOR || RM_TYP(levl[x+1][y]) == SDOOR ||
  398.        RM_TYP(levl[x][y-1]) == SDOOR || RM_TYP(levl[x][y+1]) == SDOOR ||
  399.        (RM_TYP(levl[x][y]) != HWALL && RM_TYP(levl[x][y]) != VWALL) ||
  400.        doorindex >= DOORMAX)
  401.         return(0);
  402.     return(1);
  403. }
  404.  
  405. dodoor(x,y,aroom)
  406. register x,y;
  407. register struct mkroom *aroom;
  408. {
  409.     if(doorindex >= DOORMAX) {
  410.         impossible("DOORMAX exceeded?");
  411.         return;
  412.     }
  413.     if(!okdoor(x,y) && nxcor)
  414.         return;
  415.     dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
  416. }
  417.  
  418. dosdoor(x,y,aroom,type)
  419. register x,y;
  420. register struct mkroom *aroom;
  421. register type;
  422. {
  423.     register struct mkroom *broom;
  424.     register tmp;
  425.  
  426.     if(!IS_WALL(RM_TYP(levl[x][y]))) /* avoid SDOORs with DOOR_SYM as scrsym */
  427.         type = DOOR;
  428.     RM_SET_TYP(levl[x][y], type);
  429.     if(type == DOOR)
  430.         levl[x][y].scrsym = DOOR_SYM;
  431.     aroom->doorct++;
  432.     broom = aroom+1;
  433.     if(broom->hx < 0) tmp = doorindex; else
  434.     for(tmp = doorindex; tmp > broom->fdoor; tmp--)
  435.         doors[tmp] = doors[tmp-1];
  436.     doorindex++;
  437.     doors[tmp].x = x;
  438.     doors[tmp].y = y;
  439.     for( ; broom->hx >= 0; broom++) broom->fdoor++;
  440. }
  441.  
  442. /* Only called from makerooms() */
  443. maker(lowx,ddx,lowy,ddy)
  444. schar lowx,ddx,lowy,ddy;
  445. {
  446.     register struct mkroom *croom;
  447.     register x, y, hix = lowx+ddx, hiy = lowy+ddy;
  448.     register xlim = XLIM + secret, ylim = YLIM + secret;
  449.  
  450.     if(nroom >= MAXNROFROOMS) return(0);
  451.     if(lowx < XLIM) lowx = XLIM;
  452.     if(lowy < YLIM) lowy = YLIM;
  453.     if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
  454.     if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
  455. chk:
  456.     if(hix <= lowx || hiy <= lowy) return(0);
  457.  
  458.     /* check area around room (and make room smaller if necessary) */
  459.     for(x = lowx - xlim; x <= hix + xlim; x++) {
  460.         for(y = lowy - ylim; y <= hiy + ylim; y++) {
  461.             if(RM_TYP(levl[x][y])) {
  462. #ifdef WIZARD
  463.                 if(wizard && !secret)
  464.                 pline("Strange area [%d,%d] in maker().",x,y);
  465. #endif
  466.                 if(!rn2(3)) return(0);
  467.                 if(x < lowx)
  468.                     lowx = x+xlim+1;
  469.                 else
  470.                     hix = x-xlim-1;
  471.                 if(y < lowy)
  472.                     lowy = y+ylim+1;
  473.                 else
  474.                     hiy = y-ylim-1;
  475.                 goto chk;
  476.             }
  477.         }
  478.     }
  479.  
  480.     croom = &rooms[nroom];
  481.  
  482.     /* on low levels the room is lit (usually) */
  483.     /* secret vaults are always lit */
  484.     if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) {
  485.         for(x = lowx-1; x <= hix+1; x++)
  486.             for(y = lowy-1; y <= hiy+1; y++)
  487.                 RM_SET_LIT(levl[x][y]);
  488.         croom->rlit = 1;
  489.     } else
  490.         croom->rlit = 0;
  491.     croom->lx = lowx;
  492.     croom->hx = hix;
  493.     croom->ly = lowy;
  494.     croom->hy = hiy;
  495.     croom->rtype = OROOM;
  496.     croom->doorct = croom->fdoor = 0;
  497.  
  498.     for(x = lowx-1; x <= hix+1; x++)
  499.         for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
  500.         levl[x][y].scrsym = HWALL_SYM;
  501.         RM_SET_TYP(levl[x][y], HWALL);
  502.     }
  503.     for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
  504.         for(y = lowy; y <= hiy; y++) {
  505.         levl[x][y].scrsym = VWALL_SYM;
  506.         RM_SET_TYP(levl[x][y], VWALL);
  507.     }
  508.     for(x = lowx; x <= hix; x++)
  509.         for(y = lowy; y <= hiy; y++) {
  510.         levl[x][y].scrsym = ROOM_SYM;
  511.         RM_SET_TYP(levl[x][y], ROOM);
  512.     }
  513.     levl[lowx-1][lowy-1].scrsym = TLCORN_SYM;
  514.     levl[hix+1][lowy-1].scrsym = TRCORN_SYM;
  515.     levl[lowx-1][hiy+1].scrsym = BLCORN_SYM;
  516.     levl[hix+1][hiy+1].scrsym = BRCORN_SYM;
  517.  
  518.     smeq[nroom] = nroom;
  519.     croom++;
  520.     croom->hx = -1;
  521.     nroom++;
  522.     return(1);
  523. }
  524.  
  525. makecorridors() {
  526.     register a,b;
  527.  
  528.     nxcor = 0;
  529.     for(a = 0; a < nroom-1; a++)
  530.         join(a, a+1);
  531.     for(a = 0; a < nroom-2; a++)
  532.         if(smeq[a] != smeq[a+2])
  533.         join(a, a+2);
  534.     for(a = 0; a < nroom; a++)
  535.         for(b = 0; b < nroom; b++)
  536.         if(smeq[a] != smeq[b])
  537.             join(a, b);
  538.     if(nroom > 2)
  539.         for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
  540.         a = rn2(nroom);
  541.         b = rn2(nroom-2);
  542.         if(b >= a) b += 2;
  543.         join(a, b);
  544.         }
  545. }
  546.  
  547. join(a,b)
  548. register a,b;
  549. {
  550.     coord cc,tt;
  551.     register tx, ty, xx, yy;
  552.     register struct rm *crm;
  553.     register struct mkroom *croom, *troom;
  554.     register dx, dy, dix, diy, cct;
  555.  
  556.     croom = &rooms[a];
  557.     troom = &rooms[b];
  558.  
  559.     /* find positions cc and tt for doors in croom and troom
  560.        and direction for a corridor between them */
  561.  
  562.     if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
  563.     if(troom->lx > croom->hx) {
  564.         dx = 1;
  565.         dy = 0;
  566.         xx = croom->hx+1;
  567.         tx = troom->lx-1;
  568.         finddpos(&cc, xx, croom->ly, xx, croom->hy);
  569.         finddpos(&tt, tx, troom->ly, tx, troom->hy);
  570.     } else if(troom->hy < croom->ly) {
  571.         dy = -1;
  572.         dx = 0;
  573.         yy = croom->ly-1;
  574.         finddpos(&cc, croom->lx, yy, croom->hx, yy);
  575.         ty = troom->hy+1;
  576.         finddpos(&tt, troom->lx, ty, troom->hx, ty);
  577.     } else if(troom->hx < croom->lx) {
  578.         dx = -1;
  579.         dy = 0;
  580.         xx = croom->lx-1;
  581.         tx = troom->hx+1;
  582.         finddpos(&cc, xx, croom->ly, xx, croom->hy);
  583.         finddpos(&tt, tx, troom->ly, tx, troom->hy);
  584.     } else {
  585.         dy = 1;
  586.         dx = 0;
  587.         yy = croom->hy+1;
  588.         ty = troom->ly-1;
  589.         finddpos(&cc, croom->lx, yy, croom->hx, yy);
  590.         finddpos(&tt, troom->lx, ty, troom->hx, ty);
  591.     }
  592.     xx = cc.x;
  593.     yy = cc.y;
  594.     tx = tt.x - dx;
  595.     ty = tt.y - dy;
  596.     if(nxcor && RM_TYP(levl[xx+dx][yy+dy]))
  597.         return;
  598.     dodoor(xx,yy,croom);
  599.  
  600.     cct = 0;
  601.     while(xx != tx || yy != ty) {
  602.         xx += dx;
  603.         yy += dy;
  604.  
  605.         /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
  606.         if(cct++ > 500 || (nxcor && !rn2(35)))
  607.         return;
  608.  
  609.         if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
  610.         return;     /* impossible */
  611.  
  612.         crm = &levl[xx][yy];
  613.         if(!(RM_TYP(*crm))) {
  614.         if(rn2(100)) {
  615.             RM_SET_TYP(*crm, CORR);
  616.             crm->scrsym = CORR_SYM;
  617.             if(nxcor && !rn2(50))
  618.                 (void) mkobj_at(ROCK_SYM, xx, yy);
  619.         } else {
  620.             RM_SET_TYP(*crm, SCORR);
  621.             crm->scrsym = STONE_SYM;
  622.         }
  623.         } else
  624.         if(RM_TYP(*crm) != CORR && RM_TYP(*crm) != SCORR) {
  625.         /* strange ... */
  626.         return;
  627.         }
  628.  
  629.         /* find next corridor position */
  630.         dix = abs(xx-tx);
  631.         diy = abs(yy-ty);
  632.  
  633.         /* do we have to change direction ? */
  634.         if(dy && dix > diy) {
  635.         register ddx = (xx > tx) ? -1 : 1;
  636.  
  637.         crm = &levl[xx+ddx][yy];
  638.         if(!RM_TYP(*crm) || RM_TYP(*crm) == CORR || RM_TYP(*crm) == SCORR) {
  639.             dx = ddx;
  640.             dy = 0;
  641.             continue;
  642.         }
  643.         } else if(dx && diy > dix) {
  644.         register ddy = (yy > ty) ? -1 : 1;
  645.  
  646.         crm = &levl[xx][yy+ddy];
  647.         if(!RM_TYP(*crm) || RM_TYP(*crm) == CORR || RM_TYP(*crm) == SCORR) {
  648.             dy = ddy;
  649.             dx = 0;
  650.             continue;
  651.         }
  652.         }
  653.  
  654.         /* continue straight on? */
  655.         crm = &levl[xx+dx][yy+dy];
  656.         if(!RM_TYP(*crm) || RM_TYP(*crm) == CORR || RM_TYP(*crm) == SCORR)
  657.         continue;
  658.  
  659.         /* no, what must we do now?? */
  660.         if(dx) {
  661.         dx = 0;
  662.         dy = (ty < yy) ? -1 : 1;
  663.         crm = &levl[xx+dx][yy+dy];
  664.         if(!RM_TYP(*crm) || RM_TYP(*crm) == CORR || RM_TYP(*crm) == SCORR)
  665.             continue;
  666.         dy = -dy;
  667.         continue;
  668.         } else {
  669.         dy = 0;
  670.         dx = (tx < xx) ? -1 : 1;
  671.         crm = &levl[xx+dx][yy+dy];
  672.         if(!RM_TYP(*crm) || RM_TYP(*crm) == CORR || RM_TYP(*crm) == SCORR)
  673.             continue;
  674.         dx = -dx;
  675.         continue;
  676.         }
  677.     }
  678.  
  679.     /* we succeeded in digging the corridor */
  680.     dodoor(tt.x, tt.y, troom);
  681.  
  682.     if(smeq[a] < smeq[b])
  683.         smeq[b] = smeq[a];
  684.     else
  685.         smeq[a] = smeq[b];
  686. }
  687.  
  688. make_niches()
  689. {
  690.     register int ct = rnd(nroom/2 + 1);
  691. #ifdef NEWCLASS
  692.     boolean ltptr = TRUE,
  693.         vamp = TRUE;
  694.  
  695.     while(ct--) {
  696.  
  697.         if(dlevel > 15 && !rn2(6) && ltptr) {
  698.  
  699.             ltptr = FALSE;
  700.             makeniche(LEVEL_TELEP);
  701.         } else if (dlevel > 5 && dlevel < 25
  702.                && !rn2(6) && vamp) {
  703.  
  704.             vamp = FALSE;
  705.             makeniche(TRAPDOOR);
  706.         } else    makeniche(NO_TRAP);
  707.     }
  708. #else
  709.     while(ct--) makeniche(NO_TRAP);
  710. #endif
  711. }
  712.  
  713. makevtele()
  714. {
  715.     makeniche(TELEP_TRAP);
  716. }
  717.  
  718. /* there should be one of these per trap */
  719. char    *engravings[] = {    "", "", "", "", "",
  720.                 "ad ae?ar um", "?la? ?as ?er?",
  721.                 "", "", ""
  722. #ifdef NEWTRAPS
  723.                 ,"", ""
  724. #endif
  725. #ifdef SPIDERS
  726.                 ,""
  727. #endif
  728. #ifdef NEWCLASS
  729.                 , "", "ad ae?ar um"
  730. #endif
  731. #ifdef SPELLS
  732.                 ,""
  733. #endif
  734. #ifdef KAA
  735.                 ,""
  736. #ifdef RPH
  737.                 ,""
  738. #endif
  739. #endif
  740. #ifdef SAC
  741.                 ,""
  742. #endif
  743.                 };
  744.  
  745. makeniche(trap_type)
  746. int trap_type;
  747. {
  748.     register struct mkroom *aroom;
  749.     register struct rm *rm;
  750.     register int vct = 8;
  751.     coord dd;
  752.     register dy,xx,yy;
  753.     register struct trap *ttmp;
  754.  
  755.     if(doorindex < DOORMAX)
  756.       while(vct--) {
  757.         aroom = &rooms[rn2(nroom-1)];
  758.         if(aroom->rtype != OROOM) continue; /* not an ordinary room */
  759.         if(aroom->doorct == 1 && rn2(5)) continue;
  760.         if(rn2(2)) {
  761.         dy = 1;
  762.         finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
  763.         } else {
  764.         dy = -1;
  765.         finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
  766.         }
  767.         xx = dd.x;
  768.         yy = dd.y;
  769.         if((rm = &levl[xx][yy+dy]), RM_TYP(*rm)) continue;
  770.         if(trap_type || !rn2(4)) {
  771.  
  772.         RM_SET_TYP(*rm, SCORR);
  773.         rm->scrsym = STONE_SYM;
  774.         if(trap_type) {
  775.             ttmp = maketrap(xx, yy+dy, trap_type);
  776.             ttmp->once = 1;
  777.             if (strlen(engravings[trap_type]) > 0)
  778.             make_engr_at(xx, yy-dy, engravings[trap_type]);
  779.         }
  780.         dosdoor(xx, yy, aroom, SDOOR);
  781.         } else {
  782.         RM_SET_TYP(*rm, CORR);
  783.         rm->scrsym = CORR_SYM;
  784.         if(rn2(7))
  785.             dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
  786.         else {
  787.             mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
  788.             if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
  789.         }
  790.         }
  791.         return;
  792.     }
  793. }
  794.  
  795. /* make a trap somewhere (in croom if mazeflag = 0) */
  796. mktrap(num, mazeflag, croom)
  797. #ifndef REGBUG
  798. register
  799. #endif
  800.      int num, mazeflag;
  801. #ifndef REGBUG
  802. register
  803. #endif
  804.      struct mkroom *croom;
  805. {
  806. #ifndef REGBUG
  807.     register
  808. #endif
  809.          struct trap *ttmp;
  810. #ifndef REGBUG
  811.     register
  812. #endif
  813.         int kind,nopierc,nomimic,fakedoor,fakegold,
  814. #ifdef SPIDERS
  815.             nospider,
  816. #endif
  817. #ifdef NEWCLASS
  818.             nospikes, nolevltp,
  819. #endif
  820. #ifdef SAC
  821.             nolandmine,
  822. #endif
  823.             tryct = 0;
  824.  
  825.     xchar mx,my;
  826.     extern char fut_geno[];
  827.  
  828.     if(!num || num >= TRAPNUM) {
  829.         nopierc = (dlevel < 4) ? 1 : 0;
  830. #ifdef NEWCLASS
  831.         nolevltp = (dlevel < 5) ? 1 : 0;
  832.         nospikes = (dlevel < 6) ? 1 : 0;
  833. #endif
  834. #ifdef SPIDERS
  835.         nospider = (dlevel < 7) ? 1 : 0;
  836. #endif
  837. #ifdef SAC
  838.         nolandmine = (dlevel < 5) ? 1 : 0;
  839. #endif
  840.         nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
  841.         if(index(fut_geno, 'M')) nomimic = 1;
  842.  
  843.         do {
  844.             kind = rnd(TRAPNUM-1);
  845.             if((kind == PIERC && nopierc) ||
  846.                (kind == MIMIC && nomimic)
  847. #ifdef SPIDERS
  848.                || ((kind == WEB) && nospider)
  849. #endif
  850. #ifdef NEWCLASS
  851.                || (kind == SPIKED_PIT && nospikes)
  852.                || (kind == LEVEL_TELEP && nolevltp)
  853. #endif
  854. #ifdef SAC
  855.                || (kind == LANDMINE && nolandmine)
  856. #endif
  857.                )  kind = NO_TRAP;
  858.         } while(kind == NO_TRAP);
  859.     } else kind = num;
  860.  
  861.     if(kind == MIMIC) {
  862.         register struct monst *mtmp;
  863.  
  864.         fakedoor = (!rn2(3) && !mazeflag);
  865.         fakegold = (!fakedoor && !rn2(2));
  866.         if(fakegold) goldseen = TRUE;
  867.         do {
  868.             if(++tryct > 200) return;
  869.             if(fakedoor) {
  870.                 /* note: fakedoor maybe on actual door */
  871.                 if(rn2(2)){
  872.                     if(rn2(2))  mx = croom->hx+1;
  873.                     else    mx = croom->lx-1;
  874.                     my = somey();
  875.                 } else {
  876.                     if(rn2(2))  my = croom->hy+1;
  877.                     else    my = croom->ly-1;
  878.                     mx = somex();
  879.                 }
  880.             } else if(mazeflag) {
  881.                 coord mm;
  882.                 mazexy(&mm);
  883.                 mx = mm.x;
  884.                 my = mm.y;
  885.             } else {
  886.                 mx = somex();
  887.                 my = somey();
  888.             }
  889.         } while(m_at(mx,my) || RM_TYP(levl[mx][my]) == STAIRS);
  890.         if(mtmp = makemon(PM_MIMIC,mx,my)) {
  891.             mtmp->mimic = 1;
  892.             mtmp->mappearance =
  893.             fakegold ? '$' : fakedoor ? DOOR_SYM :
  894.             (mazeflag && rn2(2)) ? AMULET_SYM :
  895. #ifdef SPELLS
  896.             "=/)%?![<>+" [ rn2(10) ];
  897. #else
  898.             "=/)%?![<>" [ rn2(9) ];
  899. #endif
  900.         }
  901.         return;
  902.     }
  903.  
  904.     do {
  905.         if(++tryct > 200)
  906.             return;
  907.         if(mazeflag){
  908.             coord mm;
  909.             mazexy(&mm);
  910.             mx = mm.x;
  911.             my = mm.y;
  912.         } else {
  913.             mx = somex();
  914.             my = somey();
  915.         }
  916.     } while(t_at(mx, my) || RM_TYP(levl[mx][my]) == STAIRS);
  917.     ttmp = maketrap(mx, my, kind);
  918. #ifdef SPIDERS
  919.     if (kind == WEB) mkmon_at ('s', mx, my);
  920. #endif
  921.     if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC)
  922.         ttmp->tseen = 1;
  923. }
  924.  
  925. #ifdef FOUNTAINS
  926. mkfount(mazeflag,croom)
  927. register struct mkroom *croom;
  928. register mazeflag;
  929. {
  930.       register xchar mx,my;
  931.       register int tryct = 0;
  932.  
  933.       do {
  934.           if(++tryct > 200)
  935.               return;
  936.           if(mazeflag){
  937.               coord mm;
  938.               mazexy(&mm);
  939.               mx = mm.x;
  940.               my = mm.y;
  941.           } else {
  942.               mx = somex();
  943.               my = somey();
  944.           }
  945.       } while(t_at(mx, my) || RM_TYP(levl[mx][my]) == STAIRS
  946. #ifdef NEWCLASS
  947.           || IS_THRONE(RM_TYP(levl[mx][my]))
  948. #endif
  949.          );
  950.  
  951.        /* Put a fountain at mx, my */
  952.  
  953.        RM_SET_TYP(levl[mx][my], FOUNTAIN);
  954.        levl[mx][my].scrsym = FOUNTAIN_SYM;
  955.  
  956. }
  957. #endif /* FOUNTAINS /**/
  958.  
  959. #ifdef SINKS
  960. mksink(croom)
  961. register struct mkroom *croom;
  962. {
  963.       register xchar mx,my;
  964.       register int tryct = 0;
  965.  
  966.       do {
  967.           if(++tryct > 200)
  968.               return;
  969.           mx = somex();
  970.           my = somey();
  971.       } while(t_at(mx, my) || RM_TYP(levl[mx][my]) == STAIRS
  972. #ifdef FOUNTAINS
  973.           || IS_FOUNTAIN(RM_TYP(levl[mx][my]))
  974. #endif
  975. #ifdef NEWCLASS
  976.           || IS_THRONE(RM_TYP(levl[mx][my]))
  977. #endif
  978.          );
  979.  
  980.        /* Put a sink at mx, my */
  981.  
  982.        RM_SET_TYP(levl[mx][my], SINK);
  983.        levl[mx][my].scrsym = SINK_SYM;
  984.  
  985. }
  986. #endif /* SINKS /**/
  987.